// WebGL全景视频播放器类
class YbPano {
    constructor(container, panorama, config = {}) {
		this.container = typeof container == 'string' ? document.querySelector(container) : container
		this.config = {...YbPano.DEFAULT_CONFIG,...config}
        this.canvas = null;
        this.gl = null;
        this.video = panorama;
        this.texture = null;
        this.program = null;
        this.buffers = {};
        this.attributes = {};
        this.uniforms = {};
        
        // 视角控制
        this.yaw = 0;        // 水平旋转（左右）
        this.pitch = 0;      // 垂直视角（上下）
        this.isDragging = false;
        this.lastMouseX = 0;
        this.lastMouseY = 0;
        
        // 陀螺仪控制
        this.gyroEnabled = false;
        this.gyroAlpha = 0;
        this.gyroBeta = 0;
        this.gyroGamma = 0;
        this.gyroSensitivity = 10.0;
        
        // 惯性效果相关变量
        this.velocityYaw = 0;
        this.velocityPitch = 0;
        this.lastDragTime = 0;
        this.isInertia = false;
		
		//注册事件
		this._event = {}
        
        // 初始化WebGL
        this.initWebGL();
        if (!this.gl) {
			this.emit('error', '您的浏览器不支持WebGL，无法播放全景视频')
            return;
        }
        
        // 初始化着色器和缓冲区
        this.initShaders();
        this.initBuffers();
        
        // 设置事件监听
        this.initEventListeners();
    }
	static DEFAULT_CONFIG = {
		controlsType: 'drag',//控制器类型 drag-手指或鼠标拖动 gyro-陀螺仪控制 both-陀螺仪和拖动
		disableDragReverse: false,//关闭反方向拖拽旋转（反向拖拽更符合人的直觉）
		disableInertia: false,//关闭惯性滑动
		inertiaStrength: 0.8,//惯性强度 0-1
		dampingFactor: 0.03//阻尼系数 (0-1)
	}
    
    // 初始化WebGL上下文
    initWebGL() {
        try {
			this.canvas = document.createElement('CANVAS')
			this.container.appendChild(this.canvas)
            this.gl = this.canvas.getContext('webgl') || this.canvas.getContext('experimental-webgl');
            if (!this.gl) {
                return false;
            }
            
            // 设置视口大小
			this._bindUpdateSize = this.updateSize.bind(this)
            this.updateSize();
            window.addEventListener('resize', this._bindUpdateSize);
            
            // 启用深度测试
            this.gl.enable(this.gl.DEPTH_TEST);
            this.gl.depthFunc(this.gl.LEQUAL);
            
            // 设置清除颜色
            this.gl.clearColor(0.0, 0.0, 0.0, 1.0);
            
            return true;
        } catch (e) {
			this.emit('error', 'WebGL初始化失败:', e.toiString())
            return false;
        }
    }
    
    // 调整画布大小
    updateSize() {
        const container = this.canvas.parentElement;
        this.canvas.width = container.clientWidth;
        this.canvas.height = container.clientHeight;
        
        if (this.gl) {
            this.gl.viewport(0, 0, this.canvas.width, this.canvas.height);
        }
    }
    
    // 初始化着色器
    initShaders() {
        const gl = this.gl;
        
        // 顶点着色器源码 - 修复纹理坐标问题
        const vertexShaderSource = `
            attribute vec3 aVertexPosition;
            attribute vec2 aTextureCoord;
            
            uniform mat4 uModelViewMatrix;
            uniform mat4 uProjectionMatrix;
            
            varying vec2 vTextureCoord;
            
            void main(void) {
                gl_Position = uProjectionMatrix * uModelViewMatrix * vec4(aVertexPosition, 1.0);
                // 修复纹理上下颠倒问题 - 翻转Y坐标
                vTextureCoord = vec2(aTextureCoord.x, 1.0 - aTextureCoord.y);
            }
        `;
        
        // 片段着色器源码
        const fragmentShaderSource = `
            precision mediump float;
            
            varying vec2 vTextureCoord;
            uniform sampler2D uSampler;
            
            void main(void) {
                gl_FragColor = texture2D(uSampler, vTextureCoord);
            }
        `;
        
        // 创建着色器程序
        this.program = this.createShaderProgram(vertexShaderSource, fragmentShaderSource);
        
        if (!this.program) {
			this.emit('error', '着色器程序创建失败')
            return;
        }
        
        // 获取属性位置
        this.attributes.vertexPosition = gl.getAttribLocation(this.program, 'aVertexPosition');
        this.attributes.textureCoord = gl.getAttribLocation(this.program, 'aTextureCoord');
        
        // 获取uniform位置
        this.uniforms.modelViewMatrix = gl.getUniformLocation(this.program, 'uModelViewMatrix');
        this.uniforms.projectionMatrix = gl.getUniformLocation(this.program, 'uProjectionMatrix');
        this.uniforms.sampler = gl.getUniformLocation(this.program, 'uSampler');
    }
    
    // 创建着色器程序
    createShaderProgram(vsSource, fsSource) {
        const gl = this.gl;
        
        // 创建顶点着色器
        const vertexShader = this.compileShader(gl.VERTEX_SHADER, vsSource);
        if (!vertexShader) return null;
        
        // 创建片段着色器
        const fragmentShader = this.compileShader(gl.FRAGMENT_SHADER, fsSource);
        if (!fragmentShader) return null;
        
        // 创建着色器程序
        const shaderProgram = gl.createProgram();
        gl.attachShader(shaderProgram, vertexShader);
        gl.attachShader(shaderProgram, fragmentShader);
        gl.linkProgram(shaderProgram);
        
        if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
            console.error('无法初始化着色器程序: ' + gl.getProgramInfoLog(shaderProgram));
            return null;
        }
        
        return shaderProgram;
    }
    
    // 编译着色器
    compileShader(type, source) {
        const gl = this.gl;
        const shader = gl.createShader(type);
        
        gl.shaderSource(shader, source);
        gl.compileShader(shader);
        
        if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
            console.error('编译着色器时出错: ' + gl.getShaderInfoLog(shader));
            gl.deleteShader(shader);
            return null;
        }
        
        return shader;
    }
    
    // 初始化缓冲区
    initBuffers() {
        const gl = this.gl;
        
        // 创建球体顶点数据 - 修复球体方向
        const sphereData = this.createSphere(1.0, 72, 36);
        
        // 创建顶点位置缓冲区
        this.buffers.vertex = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, this.buffers.vertex);
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(sphereData.vertices), gl.STATIC_DRAW);
        
        // 创建纹理坐标缓冲区
        this.buffers.textureCoord = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, this.buffers.textureCoord);
        gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(sphereData.textureCoords), gl.STATIC_DRAW);
        
        // 创建索引缓冲区
        this.buffers.indices = gl.createBuffer();
        gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.buffers.indices);
        gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(sphereData.indices), gl.STATIC_DRAW);
        
        this.buffers.numIndices = sphereData.indices.length;
    }
    
    // 创建球体几何数据 - 修复球体方向
    createSphere(radius, widthSegments, heightSegments) {
        const vertices = [];
        const textureCoords = [];
        const indices = [];
        
        for (let y = 0; y <= heightSegments; y++) {
            for (let x = 0; x <= widthSegments; x++) {
                const u = x / widthSegments;
                const v = y / heightSegments;
                
                const theta = u * Math.PI * 2;
                const phi = v * Math.PI;
                
                const sinTheta = Math.sin(theta);
                const cosTheta = Math.cos(theta);
                const sinPhi = Math.sin(phi);
                const cosPhi = Math.cos(phi);
                
                // 顶点位置 - 修复球体方向
                const px = radius * cosTheta * sinPhi;
                const py = radius * cosPhi;
                const pz = radius * sinTheta * sinPhi;
                
                vertices.push(px, py, pz);
                
                // 纹理坐标 - 修复纹理映射
                textureCoords.push(u, v);
            }
        }
        
        // 生成索引 - 修复三角形方向
        for (let y = 0; y < heightSegments; y++) {
            for (let x = 0; x < widthSegments; x++) {
                const first = (y * (widthSegments + 1)) + x;
                const second = first + widthSegments + 1;
                
                // 修复三角形缠绕顺序
                indices.push(first, second, first + 1);
                indices.push(second, second + 1, first + 1);
            }
        }
        
        return { vertices, textureCoords, indices };
    }
    
    // 创建纹理 - 修复纹理设置
    createTexture() {
        const gl = this.gl;
        
        // 如果纹理已存在，先删除
        if (this.texture) {
            gl.deleteTexture(this.texture);
        }
        
        // 创建纹理
        this.texture = gl.createTexture();
        gl.bindTexture(gl.TEXTURE_2D, this.texture);
        
        // 设置纹理参数 - 修复纹理过滤
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
        
        // 上传视频帧到纹理 - 修复像素存储格式
        gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); // 修复上下颠倒的关键设置
        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.video);
    }
    
    // 更新纹理（在视频播放时调用）
    updateTexture() {
        const gl = this.gl;
        if (this.texture && this.video.readyState >= this.video.HAVE_CURRENT_DATA) {
            gl.bindTexture(gl.TEXTURE_2D, this.texture);
            gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); // 修复上下颠倒的关键设置
            gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.video);
        }
    }
    
    // 渲染场景
    render() {
        if (!this.gl || !this.program) return;
        const gl = this.gl;
        
        // 清除画布
        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
        // 如果视频已加载，更新纹理并渲染
        if (this.texture) {
            this.updateTexture();
            // 使用着色器程序
            gl.useProgram(this.program);
            
            // 设置顶点属性
            gl.bindBuffer(gl.ARRAY_BUFFER, this.buffers.vertex);
            gl.vertexAttribPointer(this.attributes.vertexPosition, 3, gl.FLOAT, false, 0, 0);
            gl.enableVertexAttribArray(this.attributes.vertexPosition);
            gl.bindBuffer(gl.ARRAY_BUFFER, this.buffers.textureCoord);
            gl.vertexAttribPointer(this.attributes.textureCoord, 2, gl.FLOAT, false, 0, 0);
            gl.enableVertexAttribArray(this.attributes.textureCoord);
            // 绑定索引缓冲区
            gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.buffers.indices);
            
            // 设置投影矩阵
            const projectionMatrix = this.createProjectionMatrix();
            gl.uniformMatrix4fv(this.uniforms.projectionMatrix, false, projectionMatrix);
            
            // 设置模型视图矩阵 - 修复视角控制
            const modelViewMatrix = this.createModelViewMatrix();
            gl.uniformMatrix4fv(this.uniforms.modelViewMatrix, false, modelViewMatrix);
            
            // 绑定纹理
            gl.activeTexture(gl.TEXTURE0);
            gl.bindTexture(gl.TEXTURE_2D, this.texture);
            gl.uniform1i(this.uniforms.sampler, 0);
            
            // 绘制球体 - 修复渲染模式
            gl.drawElements(gl.TRIANGLES, this.buffers.numIndices, gl.UNSIGNED_SHORT, 0);
        }
        
        // 应用惯性效果
        this.applyInertia();
        
        // 请求下一帧
        requestAnimationFrame(() => this.render());
    }
    
    // 应用惯性效果
    applyInertia() {
        if (this.isInertia) {
            // 应用速度
            this.yaw += this.velocityYaw;
            this.pitch += this.velocityPitch;
            
            // 限制垂直视角角度
            this.pitch = Math.max(-Math.PI/2, Math.min(Math.PI/2, this.pitch));
            
            // 应用阻尼（逐渐减速）
            this.velocityYaw *= (1 - this.config.dampingFactor);
            this.velocityPitch *= (1 - this.config.dampingFactor);
            
            // 如果速度很小，停止惯性
            if (Math.abs(this.velocityYaw) < 0.0001 && Math.abs(this.velocityPitch) < 0.0001) {
                this.isInertia = false;
                this.velocityYaw = 0;
                this.velocityPitch = 0;
            }
        }
    }
    
    // 创建投影矩阵
    createProjectionMatrix() {
        const fieldOfView = 60 * Math.PI / 180; // 视野角度
        const aspect = this.canvas.width / this.canvas.height;
        const zNear = 0.1;
        const zFar = 100.0;
        
        const projectionMatrix = new Float32Array(16);
        
        const f = 1.0 / Math.tan(fieldOfView / 2);
        projectionMatrix[0] = f / aspect;
        projectionMatrix[5] = f;
        projectionMatrix[10] = (zFar + zNear) / (zNear - zFar);
        projectionMatrix[11] = -1;
        projectionMatrix[14] = (2 * zFar * zNear) / (zNear - zFar);
        
        return projectionMatrix;
    }
    
    // 创建模型视图矩阵 - 修复视角控制
    createModelViewMatrix() {
        const modelViewMatrix = new Float32Array(16);
        
        // 初始化为单位矩阵
        for (let i = 0; i < 16; i++) {
            modelViewMatrix[i] = i % 5 === 0 ? 1 : 0; // 对角线为1
        }
        
        // 将相机移动到球体中心
        modelViewMatrix[14] = -0.1; // Z轴平移
        
        // 应用旋转 - 修复控制逻辑
        this.applyRotation(modelViewMatrix, this.yaw, this.pitch);
        
        return modelViewMatrix;
    }
    
    // 应用旋转到矩阵 - 修复控制逻辑
    applyRotation(matrix, yaw, pitch) {
        // 创建绕Y轴旋转矩阵（水平旋转）
        const cosYaw = Math.cos(yaw);
        const sinYaw = Math.sin(yaw);
        
        // 创建绕X轴旋转矩阵（垂直视角）
        const cosPitch = Math.cos(pitch);
        const sinPitch = Math.sin(pitch);
        
        // 组合旋转矩阵：先绕Y轴旋转，再绕X轴旋转
        const combinedMatrix = [
            cosYaw, sinYaw * sinPitch, sinYaw * cosPitch, 0,
            0, cosPitch, -sinPitch, 0,
            -sinYaw, cosYaw * sinPitch, cosYaw * cosPitch, 0,
            0, 0, 0, 1
        ];
        
        // 应用组合旋转矩阵
        this.multiplyMatrices(matrix, combinedMatrix);
    }
    
    // 矩阵乘法辅助函数
    multiplyMatrices(a, b) {
        const result = new Float32Array(16);
        
        for (let i = 0; i < 4; i++) {
            for (let j = 0; j < 4; j++) {
                result[j * 4 + i] = 0;
                for (let k = 0; k < 4; k++) {
                    result[j * 4 + i] += a[k * 4 + i] * b[j * 4 + k];
                }
            }
        }
        
        // 将结果复制回原矩阵
        for (let i = 0; i < 16; i++) {
            a[i] = result[i];
        }
    }
    
    // 事件监听器初始化
    initEventListeners() {
        // 鼠标事件
        this.canvas.addEventListener('mousedown', this.onMouseDown.bind(this));
        this.canvas.addEventListener('mousemove', this.onMouseMove.bind(this));
        this.canvas.addEventListener('mouseup', this.onMouseUp.bind(this));
        this.canvas.addEventListener('wheel', this.onWheel.bind(this));
        
        // 触摸事件
        this.canvas.addEventListener('touchstart', this.onTouchStart.bind(this));
        this.canvas.addEventListener('touchmove', this.onTouchMove.bind(this));
        this.canvas.addEventListener('touchend', this.onTouchEnd.bind(this));
        
        // 键盘事件
        document.addEventListener('keydown', this.onKeyDown.bind(this));
        
        // 设置初始光标样式
        this.canvas.style.cursor = 'grab';
        
        // 陀螺仪事件
        this.initGyro();
    }
    
    // 初始化陀螺仪
    initGyro() {
        if (typeof DeviceOrientationEvent !== 'undefined' && typeof DeviceOrientationEvent.requestPermission === 'function') {
            // iOS 13+ 需要请求权限
            this.requestGyroPermission();
        } else if (window.DeviceOrientationEvent) {
            // 其他支持陀螺仪的浏览器
            window.addEventListener('deviceorientation', this.onDeviceOrientation.bind(this));
            this.gyroEnabled = true;
            this.gyroInitialized = false;
            this.gyroQuaternion = { x: 0, y: 0, z: 0, w: 1 };
        } else {
            this.emit('gyrostatus', {
                errCode: 1,
                errMsg: '不支持陀螺仪'
            });
        }
    }
    
    // 请求陀螺仪权限
    requestGyroPermission() {
        if (typeof DeviceOrientationEvent.requestPermission === 'function') {
            DeviceOrientationEvent.requestPermission()
                .then(permissionState => {
                    if (permissionState === 'granted') {
						this._binddeviceOrientation = this.onDeviceOrientation.bind(this)
                        window.addEventListener('deviceorientation', this._binddeviceOrientation);
                        this.gyroEnabled = true;
                    } else {
						this.emit('gyrostatus', {
							errCode: 2,
							errMsg: '请求陀螺仪权限被拒绝'
						})
                    }
                })
                .catch(err => {
					this.emit('gyrostatus', {
						errCode: 3,
						errMsg: '请求陀螺仪权限失败：' + err.toString()
					})
				});
        }
    }
    
    // 设备方向事件处理
    onDeviceOrientation(event) {
        if (this.config.controlsType === 'gyro' || this.config.controlsType === 'both') {
            if (!this.gyroEnabled) return;
            
            // 确保有有效的陀螺仪数据
            if (event.alpha === null || event.beta === null || event.gamma === null) {
                return;
            }
            
            if (!this.gyroInitialized) {
                this.setOrientationFromDeviceEvent(event);
                this.gyroInitialized = true;
                return;
            }
            
            this.updateOrientation(event);
        }
    }
	
	// 设置初始方向
	setOrientationFromDeviceEvent(event) {
	    // 根据Three.js的实现原理，需要将设备坐标系转换为WebGL坐标系:cite[1]
	    const alpha = event.alpha ? THREE.MathUtils.degToRad(event.alpha) : 0;
	    const beta = event.beta ? THREE.MathUtils.degToRad(event.beta) : 0;
	    const gamma = event.gamma ? THREE.MathUtils.degToRad(event.gamma) : 0;
	    const orient = this.getScreenOrientationAngle();
	    
	    // 使用欧拉角设置四元数:cite[1]
	    const euler = new THREE.Euler();
	    euler.set(beta, alpha, -gamma, 'YXZ'); // 关键：坐标系转换
	    
	    this.gyroQuaternion = new THREE.Quaternion().setFromEuler(euler);
	    
	    // 应用屏幕方向补偿
	    const zee = new THREE.Vector3(0, 0, 1);
	    const q0 = new THREE.Quaternion();
	    q0.setFromAxisAngle(zee, -orient);
	    this.gyroQuaternion.multiply(q0);
	    
	    // 应用设备方向补偿（让相机看向设备背面）:cite[1]
	    const q1 = new THREE.Quaternion(-Math.sqrt(0.5), 0, 0, Math.sqrt(0.5)); // - PI/2 around the x-axis
	    this.gyroQuaternion.multiply(q1);
	    
	    // 保存初始四元数用于相对计算
	    this.gyroBaseQuaternion = this.gyroQuaternion.clone();
	    this.lastGyroQuaternion = this.gyroQuaternion.clone();
	}
	
	// 更新方向
	updateOrientation(event) {
	    const alpha = event.alpha ? THREE.MathUtils.degToRad(event.alpha) : 0;
	    const beta = event.beta ? THREE.MathUtils.degToRad(event.beta) : 0;
	    const gamma = event.gamma ? THREE.MathUtils.degToRad(event.gamma) : 0;
	    const orient = this.getScreenOrientationAngle();
	    
	    // 使用欧拉角设置四元数:cite[1]
	    const euler = new THREE.Euler();
	    euler.set(beta, alpha, -gamma, 'YXZ');
	    
	    const currentQuaternion = new THREE.Quaternion().setFromEuler(euler);
	    
	    // 应用屏幕方向补偿
	    const zee = new THREE.Vector3(0, 0, 1);
	    const q0 = new THREE.Quaternion();
	    q0.setFromAxisAngle(zee, -orient);
	    currentQuaternion.multiply(q0);
	    
	    // 应用设备方向补偿:cite[1]
	    const q1 = new THREE.Quaternion(-Math.sqrt(0.5), 0, 0, Math.sqrt(0.5));
	    currentQuaternion.multiply(q1);
	    
	    // 计算相对于初始方向的旋转
	    const relativeQuaternion = this.gyroBaseQuaternion.clone().invert().multiply(currentQuaternion);
	    
	    // 转换为欧拉角用于控制
	    const eulerResult = new THREE.Euler().setFromQuaternion(relativeQuaternion, 'YXZ');
	    
	    // 根据控制模式更新视角
	    this.updateViewFromGyro(eulerResult.y, eulerResult.x);
	    
	    this.lastGyroQuaternion = currentQuaternion.clone();
	}
	
	// 根据陀螺仪数据更新视角
	updateViewFromGyro(yaw, pitch) {
	    const sensitivity = this.gyroSensitivity * 0.01;
	    
	    switch (this.config.controlsType) {
	        case 'gyro':
	            // 仅陀螺仪模式
	            this.yaw = -yaw * sensitivity;
	            this.pitch = -pitch * sensitivity;
	            break;
	            
	        case 'both':
	            // 混合模式：陀螺仪控制基础方向，拖拽控制相对偏移
	            // 陀螺仪提供基础旋转
	            const baseYaw = -yaw * sensitivity;
	            const basePitch = -pitch * sensitivity;
	            
	            // 结合拖拽偏移量
	            this.yaw = baseYaw + this.dragYawOffset;
	            this.pitch = basePitch + this.dragPitchOffset;
	            break;
	            
	        default:
	            return;
	    }
	    
	    // 限制垂直视角角度
	    this.pitch = Math.max(-Math.PI/2, Math.min(Math.PI/2, this.pitch));
	}
	
	// 获取屏幕方向角度
	getScreenOrientationAngle() {
	    let angle = 0;
	    
	    switch (window.orientation) {
	        case 90:
	            angle = -Math.PI / 2; // 横屏
	            break;
	        case -90:
	            angle = Math.PI / 2; // 横屏（反方向）
	            break;
	        case 180:
	            angle = Math.PI; // 倒立竖屏
	            break;
	        default:
	            angle = 0; // 正常竖屏
	    }
	    
	    return angle;
	}
	
	// 工具函数：标准化角度到 [-π, π]
	normalizeAngle(angle) {
	    while (angle > Math.PI) angle -= 2 * Math.PI;
	    while (angle < -Math.PI) angle += 2 * Math.PI;
	    return angle;
	}
    
    // 鼠标事件处理 - 修复控制逻辑
    onMouseDown(event) {
        if (this.config.controlsType === 'drag' || this.config.controlsType === 'both') {
            this.isDragging = true;
            this.isInertia = false;
            this.velocityYaw = 0;
            this.velocityPitch = 0;
            this.lastMouseX = event.clientX;
            this.lastMouseY = event.clientY;
            this.lastDragTime = Date.now();
            this.canvas.style.cursor = 'grabbing';
            
            // 混合模式下记录当前拖拽起始点
            if (this.config.controlsType === 'both') {
                this.dragStartYaw = this.yaw;
                this.dragStartPitch = this.pitch;
                // 保存当前的陀螺仪基础方向
                this.dragGyroBaseYaw = this.yaw;
                this.dragGyroBasePitch = this.pitch;
            }
        }
    }
    
    onMouseMove(event) {
        if (!this.isDragging || (this.config.controlsType !== 'drag' && this.config.controlsType !== 'both')) return;
        
        const currentTime = Date.now();
        const deltaTime = Math.max(1, currentTime - this.lastDragTime);
        this.lastDragTime = currentTime;
        
        const deltaX = event.clientX - this.lastMouseX;
        const deltaY = event.clientY - this.lastMouseY;
        
        let yawDelta, pitchDelta;
        
        if (!this.config.disableDragReverse) {
            yawDelta = deltaX * 0.005;
            pitchDelta = deltaY * 0.005;
        } else {
            yawDelta = -deltaX * 0.005;
            pitchDelta = -deltaY * 0.005;
        }
        
        if (this.config.controlsType === 'drag') {
            // 仅拖拽模式
            this.yaw += yawDelta;
            this.pitch += pitchDelta;
            
            this.velocityYaw = yawDelta / (deltaTime / 16) * this.config.inertiaStrength;
            this.velocityPitch = pitchDelta / (deltaTime / 16) * this.config.inertiaStrength;
            
        } else if (this.config.controlsType === 'both') {
            // 混合模式：只更新拖拽偏移量
            this.dragYawOffset += yawDelta;
            this.dragPitchOffset += pitchDelta;
            
            // 限制拖拽偏移范围
            this.dragYawOffset = this.normalizeAngle(this.dragYawOffset);
            this.dragPitchOffset = Math.max(-Math.PI, Math.min(Math.PI, this.dragPitchOffset));
            
            this.velocityYaw = yawDelta / (deltaTime / 16) * this.config.inertiaStrength;
            this.velocityPitch = pitchDelta / (deltaTime / 16) * this.config.inertiaStrength;
        }
        
        this.pitch = Math.max(-Math.PI/2, Math.min(Math.PI/2, this.pitch));
        
        this.lastMouseX = event.clientX;
        this.lastMouseY = event.clientY;
    }
    
    onMouseUp() {
        if (this.isDragging) {
            this.isDragging = false;
            // 开始惯性效果
            this.isInertia = true;
        }
        this.canvas.style.cursor = 'grab';
    }
    
    onWheel(event) {
        // 可以通过滚轮调整视野，这里简单实现为缩放
        // 实际实现需要调整视野角度
        event.preventDefault();
    }
    
    // 触摸事件处理 - 修复控制逻辑
    onTouchStart(event) {
        if ((this.config.controlsType === 'drag' || this.config.controlsType === 'both') && event.touches.length === 1) {
            this.isDragging = true;
            this.isInertia = false; // 停止惯性
            this.velocityYaw = 0;
            this.velocityPitch = 0;
            this.lastMouseX = event.touches[0].clientX;
            this.lastMouseY = event.touches[0].clientY;
            this.lastDragTime = Date.now();
            event.preventDefault();
        }
    }
    
    onTouchMove(event) {
        if (!this.isDragging || event.touches.length !== 1 || (this.config.controlsType !== 'drag' && this.config.controlsType !== 'both')) return;
        
        const currentTime = Date.now();
        const deltaTime = Math.max(1, currentTime - this.lastDragTime);
        this.lastDragTime = currentTime;
        
        const deltaX = event.touches[0].clientX - this.lastMouseX;
        const deltaY = event.touches[0].clientY - this.lastMouseY;
        
		//开启反向拖动
		if ( !this.config.disableDragReverse ) {
			this.yaw += deltaX * 0.005;  // 左右拖动 -> 水平旋转
			this.pitch += deltaY * 0.005; // 上下拖动 -> 垂直视角
			// 计算速度（用于惯性效果）
			this.velocityYaw = (deltaX * 0.005) / (deltaTime / 16) * this.config.inertiaStrength;
			this.velocityPitch = (deltaY * 0.005) / (deltaTime / 16) * this.config.inertiaStrength;
		} else {
			//关闭反向拖动
			this.yaw -= deltaX * 0.005;  // 左右拖动 -> 水平旋转
			this.pitch -= deltaY * 0.005; // 上下拖动 -> 垂直视角
			// 计算速度（用于惯性效果）
			this.velocityYaw = (-deltaX * 0.005) / (deltaTime / 16) * this.config.inertiaStrength;
			this.velocityPitch = (-deltaY * 0.005) / (deltaTime / 16) * this.config.inertiaStrength;
		}
        
        // 限制垂直视角角度
        this.pitch = Math.max(-Math.PI/2, Math.min(Math.PI/2, this.pitch));
        
        this.lastMouseX = event.touches[0].clientX;
        this.lastMouseY = event.touches[0].clientY;
        
        event.preventDefault();
    }
    
    onTouchEnd() {
        if (this.isDragging) {
            this.isDragging = false;
            // 开始惯性效果
            this.isInertia = true;
        }
    }
    
    // 键盘事件处理
    onKeyDown(event) {
        switch(event.code) {
            case 'Space':
                event.preventDefault();
                this.togglePlay();
                break;
            case 'ArrowLeft':
                this.yaw -= 0.1; // 左箭头 -> 向左旋转
                break;
            case 'ArrowRight':
                this.yaw += 0.1; // 右箭头 -> 向右旋转
                break;
            case 'ArrowUp':
                this.pitch = Math.max(-Math.PI/2, this.pitch - 0.1); // 上箭头 -> 向上看
                break;
            case 'ArrowDown':
                this.pitch = Math.min(Math.PI/2, this.pitch + 0.1); // 下箭头 -> 向下看
                break;
        }
    }
    
    // 设置控制模式
    setControlsType(type) {
		// 重置相关状态
		if (type !== this.config.controlsType) {
		    this.gyroInitialized = false;
		    this.dragYawOffset = 0;
		    this.dragPitchOffset = 0;
		    
		    // 重置视角
		    if (type === 'drag') {
		        this.yaw = 0;
		        this.pitch = 0;
		    }
		}
        this.config.controlsType = type;
        // 如果是陀螺仪模式但未启用，尝试请求权限
        if ((type === 'gyro' || type === 'both') && !this.gyroEnabled) {
            this.requestGyroPermission();
        }
    }
	
	//获取控制模式
	getControlsType () {
		return this.config.controlsType
	}
    
    // 重置视角
    resetView() {
        this.yaw = 0;
        this.pitch = 0;
        this.dragYawOffset = 0;
        this.dragPitchOffset = 0;
        this.velocityYaw = 0;
        this.velocityPitch = 0;
        this.isInertia = false;
        this.gyroInitialized = false; // 重置陀螺仪基准
    }
    
    // 设置惯性强度
    setInertiaStrength(value) {
        this.config.inertiaStrength = value / 100;
    }
    
    // 设置阻尼系数
    setDampingFactor(value) {
        this.config.dampingFactor = value / 100;
    }
    
    // 设置陀螺仪灵敏度
    setGyroSensitivity(value) {
        this.gyroSensitivity = value / 100;
    }
    
	//注册事件
	on (name, func) {
		this._event[name] = func
	}
	//主动派发事件
	emit (name, value) {
		this._event[name] && this._event[name](value)
	}
	//开始播放
	start () {
		//创建视频纹理
		this.createTexture()
		// 开始渲染循环
		this.render();
	}
	
	// 销毁播放器实例的完整方法
	destroy() {		
	    // 1. 删除视频引用，避免占用导致视频无法正确销毁
	    if (this.video) {
	        this.video = null
	    }
	    
	    // 2. 停止渲染循环
	    this.isInertia = false;
	    this.isDragging = false;
	    
	    // 3. 移除所有事件监听器
	    this.removeEventListeners();
	    
	    // 4. 释放WebGL资源
	    if (this.gl) {
	        const gl = this.gl;
	        
	        // 删除纹理
	        if (this.texture) {
	            gl.deleteTexture(this.texture);
	            this.texture = null;
	        }
	        
	        // 删除缓冲区
	        if (this.buffers.vertex) {
	            gl.deleteBuffer(this.buffers.vertex);
	            this.buffers.vertex = null;
	        }
	        if (this.buffers.textureCoord) {
	            gl.deleteBuffer(this.buffers.textureCoord);
	            this.buffers.textureCoord = null;
	        }
	        if (this.buffers.indices) {
	            gl.deleteBuffer(this.buffers.indices);
	            this.buffers.indices = null;
	        }
	        
	        // 删除着色器程序
	        if (this.program) {
	            gl.deleteProgram(this.program);
	            this.program = null;
	        }
	        
	        // 清除WebGL上下文
	        gl.getExtension('WEBGL_lose_context')?.loseContext();
	        this.gl = null;
	    }
	    
	    // 5. 清除所有引用
	    this.attributes = {};
	    this.uniforms = {};
	    this.buffers = {};
	    
	    // 6. 如果创建了额外的DOM元素，移除它们
	    if (this.canvas && this.canvas.parentNode) {
	        this.canvas.parentNode.removeChild(this.canvas);
	    }
		//抛出销毁事件
	    this.emit('destroyed')
		
		//注销注册事件
		this._event = {}
	}
	
	// 移除事件监听器的辅助方法
	removeEventListeners() {
	    // 移除鼠标事件
	    this.canvas.removeEventListener('mousedown', this.onMouseDown);
	    this.canvas.removeEventListener('mousemove', this.onMouseMove);
	    this.canvas.removeEventListener('mouseup', this.onMouseUp);
	    this.canvas.removeEventListener('wheel', this.onWheel);
	    
	    // 移除触摸事件
	    this.canvas.removeEventListener('touchstart', this.onTouchStart);
	    this.canvas.removeEventListener('touchmove', this.onTouchMove);
	    this.canvas.removeEventListener('touchend', this.onTouchEnd);
	    
	    // 移除键盘事件
	    document.removeEventListener('keydown', this.onKeyDown);
	    
	    // 移除陀螺仪事件
	    if (this.gyroEnabled) {
	        window.removeEventListener('deviceorientation', this._binddeviceOrientation);
	    }
	    
	    // 移除窗口调整大小事件
	    window.removeEventListener('resize', this._bindUpdateSize);
	}
}

if ( typeof window != 'undefined' ) {
	window.YbPano = YbPano
}